import { Injectable } from '@nestjs/common';
import logger from 'src/common/utils/log';
import { GameInfo } from 'src/modules/game/entities/game.entity';
import { GameService } from 'src/modules/game/game.service';
import { GroupPlayerScore } from 'src/modules/group-player-score/entities/group-player-score.entity';
import { GroupPlayerScoreService } from 'src/modules/group-player-score/group-player-score.service';
import { Group } from 'src/modules/group/entities/group.entity';
import { GroupService } from 'src/modules/group/group.service';
import { MatchInfo } from 'src/modules/match/entities/match.entity';
import { MatchService } from 'src/modules/match/match.service';
import { StageEvent } from 'src/modules/stage-event/entities/stage-event.entity';
import { StageEventService } from 'src/modules/stage-event/stage-event.service';
import { Stage } from 'src/modules/stage/entities/stage.entity';
import { Event } from 'src/modules/event/entities/event.entity';
import { StageService } from 'src/modules/stage/stage.service';
import { EventService } from 'src/modules/event/event.service';
import { EventToPlayerService } from 'src/modules/event-to-player/event-to-player.service';
import { PlayerSignupService } from 'src/modules/player-signup/service/player-signup.service';
import { Category } from 'src/modules/category/entities/category.entity';
import { CategoryService } from 'src/modules/category/category.service';
import { Tournament } from 'src/modules/tournament/entities/tournament.entity';
import { TournamentService } from 'src/modules/tournament/tournament.service';
import { Connection, EntityManager } from 'typeorm';
import { EventToPlayer } from 'src/modules/event-to-player/entities/event-to-player.entity';

@Injectable()
export class RemoveDataService {
  constructor(
    private readonly connection: Connection,
    private readonly groupService: GroupService,
    private readonly stageEventService: StageEventService,
    private readonly groupPlayerScoreService: GroupPlayerScoreService,
    private readonly matchService: MatchService,
    private readonly stageService: StageService,
    private readonly gameService: GameService,
    private readonly eventService: EventService,
    private readonly eventToPlayerService: EventToPlayerService,
    private readonly playerSignupService: PlayerSignupService,
    private readonly categoryService: CategoryService,
    private readonly tournamentService: TournamentService,
  ) {}

  // 带事务的赛事删除方法
  async deleteTournamentDataWithTransaction(
    tournaments: Tournament[],
  ): Promise<void> {
    return this.connection.transaction(async (manager) => {
      await this.deleteTournamentData(tournaments, manager);
    });
  }

  async deleteStageDataWithTransaction(stageList: Stage[]): Promise<void> {
    return this.connection.transaction(async (manager) => {
      await this.deleteStageData(stageList, manager);
    });
  }

  // 新增删除赛事方法
  async deleteTournamentData(
    tournaments: Tournament[],
    manager?: EntityManager,
  ) {
    logger.info(`deleteTournamentData ${tournaments.length} tournaments...`);
    const deleteCategories: Category[] = [];
    const deleteEvents: Event[] = [];
    const tournamentIds: number[] = [];

    tournaments.forEach((tournament) => {
      tournamentIds.push(tournament.id);
      // 收集关联的分类
      if (tournament.categories && tournament.categories.length) {
        deleteCategories.push(...tournament.categories);
        logger.info(
          `Tournament ${tournament.id} has ${tournament.categories.length} categories to delete`,
        );
      }
      // 收集直接关联的事件（非分类下的事件）
      if (tournament.events && tournament.events.length) {
        deleteEvents.push(...tournament.events);
        logger.info(
          `Tournament ${tournament.id} has ${tournament.events.length} direct events to delete`,
        );
      }
    });

    // 先删除关联的分类数据（分类会级联删除其下的事件）
    if (deleteCategories.length) {
      await this.deleteCategory(deleteCategories, manager);
    }

    // 再删除直接关联的事件数据
    if (deleteEvents.length) {
      await this.deleteEventData(deleteEvents, manager);
    }

    // 最后删除赛事本身
    if (manager) {
      await manager.delete(Tournament, tournamentIds);
    } else {
      await this.tournamentService.removeIds(tournamentIds);
    }
    logger.info(
      `finish deleteTournamentData ${tournaments.length} tournaments...`,
    );
  }

  // 新增删除分类方法
  async deleteCategory(categories: Category[], manager?: EntityManager) {
    logger.info(`deleteCategory ${categories.length} categories...`);
    const deleteEvents: Event[] = [];
    const categoryIds: number[] = [];

    categories.forEach((category) => {
      categoryIds.push(category.id);
      if (category.events && category.events.length) {
        deleteEvents.push(...category.events);
        logger.info(
          `Category ${category.id} has ${category.events.length} events to delete`,
        );
      }
    });

    // 先删除关联的事件数据
    if (deleteEvents.length) {
      await this.deleteEventData(deleteEvents, manager);
    }

    // 最后删除分类本身
    if (manager) {
      await manager.delete(Category, categoryIds);
    } else {
      await this.categoryService.removeIds(categoryIds);
    }
    logger.info(`finish deleteCategory ${categories.length} categories...`);
  }

  async deleteEventData(events: Event[], manager?: EntityManager) {
    logger.info(`deleteEventData ${events.length} events...`);
    const deleteStages: Stage[] = [];
    const deleteEventToPlayers: any[] = [];
    const deletePlayerSignups: any[] = [];
    const eventIds: number[] = [];

    events.forEach((event) => {
      eventIds.push(event.id);
      if (event.stages && event.stages.length) {
        deleteStages.push(...event.stages);
      }
      if (event.eventToPlayers && event.eventToPlayers.length) {
        deleteEventToPlayers.push(...event.eventToPlayers);
      }
      if (event.playerSignups && event.playerSignups.length) {
        deletePlayerSignups.push(...event.playerSignups);
      }
    });

    // 先删除关联的阶段数据
    if (deleteStages.length) {
      await this.deleteStageData(deleteStages, manager);
    }

    // 删除事件-玩家关联数据
    if (deleteEventToPlayers.length) {
      const etpIds = deleteEventToPlayers.map((etp) => etp.id);
      if (manager) {
        await manager.delete(EventToPlayer, etpIds);
      } else {
        await this.eventToPlayerService.removeIds(etpIds);
      }
      logger.info(`deleted ${deleteEventToPlayers.length} eventToPlayers`);
    }

    // 删除玩家报名数据
    if (deletePlayerSignups.length) {
      const subPlayerSignups = deletePlayerSignups.filter(
        (ps) => ps.parentPlayerId !== null,
      );
      const topPlaerySignups = deletePlayerSignups.filter(
        (ps) => ps.parentPlayerId === null,
      );

      if (manager) {
        // 只在subPlayerSignups非空时执行删除
        if (subPlayerSignups.length) {
          await manager.delete(
            'player_signup',
            subPlayerSignups.map((ps) => ps.id),
          );
        }
        // 只在topPlaerySignups非空时执行删除
        if (topPlaerySignups.length) {
          await manager.delete(
            'player_signup',
            topPlaerySignups.map((ps) => ps.id),
          );
        }
      } else {
        // 只在subPlayerSignups非空时执行删除
        if (subPlayerSignups.length) {
          await this.playerSignupService.removeIds(
            subPlayerSignups.map((ps) => ps.id),
          );
        }
        // 只在topPlaerySignups非空时执行删除
        if (topPlaerySignups.length) {
          await this.playerSignupService.removeIds(
            topPlaerySignups.map((ps) => ps.id),
          );
        }
      }
      logger.info(`deleted ${deletePlayerSignups.length} playerSignups`);
    }

    // 最后删除事件本身
    if (manager) {
      await manager.delete(Event, eventIds);
    } else {
      await this.eventService.removeIds(eventIds);
    }
    logger.info(`finish deleteEventData ${events.length} events...`);
  }

  async deleteStageData(stages: Stage[], manager?: EntityManager) {
    logger.info(`deleteStageData ${stages.length} stages...`);
    const deleteGroups = [];
    const deleteStageEvents = [];
    const ids = [];
    stages.forEach((stage) => {
      const { groups, stageEvents } = stage;
      logger.info(
        `deleteStageData ${stage.id} groups ${groups?.length} stageEvents ${stageEvents?.length}`,
      );
      ids.push(stage.id);
      if (groups && groups.length) {
        deleteGroups.push(...groups);
      }
      if (stageEvents && stageEvents.length) {
        deleteStageEvents.push(...stageEvents);
      }
    });
    const depDeletePromises = [];
    if (deleteGroups && deleteGroups.length) {
      depDeletePromises.push(this.deleteGroupData(deleteGroups, manager));
    }
    if (deleteStageEvents && deleteStageEvents.length) {
      depDeletePromises.push(
        this.deleteStageEventData(deleteStageEvents, manager),
      );
    }
    if (depDeletePromises.length) {
      await Promise.all(depDeletePromises);
    }

    if (manager) {
      await manager.delete(Stage, ids);
    } else {
      await this.stageService.removeIds(ids);
    }
    logger.info(`finish deleteStageData ${stages.length} stages...`);
  }

  async deleteGroupData(groups: Group[], manager?: EntityManager) {
    logger.info(`deleteGroupData ${groups.length} groups...`);
    const deleteMatches = [];
    const deleteGroupPlayerScores = [];
    const ids = [];

    groups.forEach((group) => {
      const { matchInfos, groupPlayerScores } = group;
      logger.info(
        `deleteGroupData ${group.id} matchInfos ${matchInfos?.length} groupPlayerScores ${groupPlayerScores?.length}`,
      );
      ids.push(group.id);
      if (matchInfos && matchInfos.length) {
        deleteMatches.push(...matchInfos);
      }
      if (groupPlayerScores && groupPlayerScores.length) {
        deleteGroupPlayerScores.push(...groupPlayerScores);
      }
    });

    const depDeletePromises = [];
    if (deleteGroupPlayerScores && deleteGroupPlayerScores.length) {
      depDeletePromises.push(
        this.deleteGroupPlayerScoreData(deleteGroupPlayerScores, manager),
      );
    }
    if (deleteMatches && deleteMatches.length) {
      depDeletePromises.push(this.deleteMatchData(deleteMatches, manager));
    }
    if (depDeletePromises.length) {
      await Promise.all(depDeletePromises);
    }

    if (manager) {
      await manager.delete(Group, ids);
    } else {
      await this.groupService.removeIds(ids);
    }
    logger.info(`finish deleteGroupData ${groups.length} groups...`);
  }

  async deleteStageEventData(
    stageEvents: StageEvent[],
    manager?: EntityManager,
  ) {
    logger.info(`deleteStageEventData ${stageEvents.length} StageEvent...`);
    const ids = [];
    stageEvents.forEach((stageEvent) => {
      ids.push(stageEvent.id);
    });

    if (manager) {
      await manager.delete(StageEvent, ids);
    } else {
      await this.stageEventService.removeIds(ids);
    }
    logger.info(`finish deleteStageData ${stageEvents.length} StageEvent...`);
  }

  async deleteGroupPlayerScoreData(
    groupPlayerScores: GroupPlayerScore[],
    manager?: EntityManager,
  ) {
    logger.info(
      `deleteGroupPlayerScoreData ${groupPlayerScores.length} GroupPlayerScore...`,
    );
    const ids = [];
    groupPlayerScores.forEach((stageEvent) => {
      ids.push(stageEvent.id);
    });

    if (manager) {
      await manager.delete(GroupPlayerScore, ids);
    } else {
      await this.groupPlayerScoreService.removeIds(ids);
    }
    logger.info(
      `finish deleteGroupPlayerScoreData ${groupPlayerScores.length} GroupPlayerScore...`,
    );
  }

  async deleteMatchData(matches: MatchInfo[], manager?: EntityManager) {
    logger.info(`deleteMatchData ${matches.length} matches...`);
    const deleteSubMatches = [];
    const deleteGames = [];
    const ids = [];
    matches.forEach((match) => {
      const { subMatchInfos, games } = match;
      logger.info(
        `deleteMatchData ${match.id} subMatchInfos ${subMatchInfos?.length} games ${games?.length}`,
      );
      ids.push(match.id);
      if (subMatchInfos && subMatchInfos.length) {
        deleteSubMatches.push(...subMatchInfos);
      }
      if (games && games.length) {
        deleteGames.push(...games);
      }
    });

    if (deleteGames && deleteGames.length) {
      await this.deleteGameInfoData(deleteGames, manager);
    }
    if (deleteSubMatches && deleteSubMatches.length) {
      await this.deleteMatchData(deleteSubMatches, manager);
    }

    if (manager) {
      await manager.delete(MatchInfo, ids);
    } else {
      await this.matchService.removeIds(ids);
    }
    logger.info(`finish deleteMatchData ${matches.length} matches...`);
  }

  async deleteGameInfoData(gameInfos: GameInfo[], manager?: EntityManager) {
    logger.info(`deleteGameInfoData ${gameInfos.length} gameInfos...`);
    const ids = [];
    gameInfos.forEach((gameInfo) => {
      ids.push(gameInfo.id);
    });

    if (manager) {
      await manager.delete(GameInfo, ids);
    } else {
      await this.gameService.removeIds(ids);
    }
    logger.info(`finish deleteGameInfoData ${gameInfos.length} gameInfos...`);
  }
}